iT邦幫忙

2026 iThome 鐵人賽

DAY 23
0

今天對 TelegramBotService.gs 進行修改,讓 Telegram Bot 專注於作為即時營運狀態中樞,負責推送預約異動、取消規章與現場簽到/釋放狀態。


1. 調整後的推播架構與訊息範本設計

Telegram Bot 承擔以下 4 大核心推播任務:

  1. 新預約即時通知:顯示預約編號、房間名稱、預約職工 Email、時段與預約用途。
  2. 預約取消與 24HR 規章警示:標示為免費取消(CANCELLED)或遲取消(LATE_CANCELLED)。
  3. 現場簽到成功通知:即時回報職工已掃碼完成簽到。
  4. 逾時未簽到釋放警示:提醒管理團隊該時段已因逾時 15 分鐘未簽到而自動釋放(Auto-release)。

2. 後端推播服務程式碼 (TelegramBotService.gs)

請在 Apps Script 專案中更新 TelegramBotService.gs 檔案,寫入以下程式碼:

/**
 * ==============================================================================
 * Telegram Bot 即時通知服務 (TelegramBotService.gs)
 * 專案:NGO 房間與資源預約管理系統 (Build on Google AI Track)
 * 說明:實作統一的 Telegram Bot API 推播介面與格式化訊息發送邏輯。
 * ==============================================================================
 */

/**
 * 核心底層函式:發送 Telegram 訊息 (支援 HTML 標籤格式)
 * @param {string} htmlMessage - 格式化的 HTML 訊息內容
 * @returns {boolean} 發送成功與否
 */
function sendTelegramNotification(htmlMessage) {
  const config = getConfig();
  
  if (!config.TELEGRAM_BOT_TOKEN || config.TELEGRAM_BOT_TOKEN.includes("YOUR_")) {
    Logger.log("⚠️ Telegram Bot Token 未設定,跳過推播發送。");
    return false;
  }

  const url = `https://api.telegram.org/bot${config.TELEGRAM_BOT_TOKEN}/sendMessage`;
  
  const payload = {
    chat_id: config.TELEGRAM_CHAT_ID,
    text: htmlMessage,
    parse_mode: "HTML",
    disable_web_page_preview: true
  };

  const options = {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  };

  try {
    const response = UrlFetchApp.fetch(url, options);
    const result = JSON.parse(response.getContentText());
    if (result.ok) {
      return true;
    } else {
      Logger.log(`❌ Telegram 推播失敗: ${result.description}`);
      return false;
    }
  } catch (error) {
    Logger.log(`❌ UrlFetchApp 發送 Telegram 訊息異常: ${error.toString()}`);
    return false;
  }
}

/**
 * 1. 新預約成功通知範本 (由 BookingService.gs 呼叫)
 * 註:不顯示租賃費用與 Gemini AI 審查標籤
 */
function notifyNewBookingSuccess(bookingData) {
  const msg = 
    `📢 <b>【新房間預約成功通知】</b>\n` +
    `--------------------------------------\n` +
    `🆔 <b>預約編號:</b><code>${bookingData.bookingId}</code>\n` +
    `🏢 <b>預約房間:</b>${bookingData.roomName}\n` +
    `👤 <b>預約職工:</b>${bookingData.userEmail}\n` +
    `⏰ <b>預約時段:</b>${bookingData.formattedStart} - ${bookingData.formattedEnd}\n` +
    `📝 <b>用途說明:</b>${bookingData.purpose}\n` +
    `--------------------------------------\n` +
    `<i>系統已自動完成時間衝突排查並成功寫入預約。</i>`;

  return sendTelegramNotification(msg);
}

/**
 * 2. 預約取消/規章通知範本 (由 CancellationService.gs 呼叫)
 */
function notifyBookingCancellation(cancelData) {
  const msg = 
    `🚨 <b>【房間預約異動 - 取消通知】</b>\n` +
    `--------------------------------------\n` +
    `🆔 <b>預約編號:</b><code>${cancelData.bookingId}</code>\n` +
    `🏢 <b>預約房間:</b>${cancelData.roomName}\n` +
    `👤 <b>申請職工:</b>${cancelData.userEmail}\n` +
    `⏰ <b>原預約時段:</b>${cancelData.formattedStart}\n` +
    `📌 <b>取消狀態:</b>${cancelData.status}\n` +
    `💬 <b>取消原因:</b>${cancelData.reason || "未提供"}\n` +
    `--------------------------------------\n` +
    `<i>系統已依據 24HR 規章更新資料庫。</i>`;

  return sendTelegramNotification(msg);
}

/**
 * 3. 簽到與自動釋放通知範本 (由 CheckInService.gs 呼叫)
 */
function notifyCheckInStatus(checkInData) {
  let msg = "";
  if (checkInData.type === "CHECK_IN_SUCCESS") {
    msg = 
      `✅ <b>【現場簽到成功通知】</b>\n` +
      `--------------------------------------\n` +
      `🆔 <b>預約編號:</b><code>${checkInData.bookingId}</code>\n` +
      `🏢 <b>房間:</b>${checkInData.roomName}\n` +
      `👤 <b>職工:</b>${checkInData.userEmail}\n` +
      `⏰ <b>簽到時間:</b>${checkInData.formattedTime}\n` +
      `--------------------------------------\n` +
      `<i>現場 QR Code 掃碼簽到完成。</i>`;
  } else if (checkInData.type === "AUTO_RELEASE") {
    msg = 
      `⚠️ <b>【資源逾時自動釋放警示】</b>\n` +
      `--------------------------------------\n` +
      `🆔 <b>預約編號:</b><code>${checkInData.bookingId}</code>\n` +
      `🏢 <b>房間:</b>${checkInData.roomName}\n` +
      `👤 <b>原申請人:</b>${checkInData.userEmail}\n` +
      `⏰ <b>原定時間:</b>${checkInData.formattedStart}\n` +
      `📌 <b>說明:</b>超過 15 分鐘未完成現場簽到,系統已自動釋放該時段供他人預約。\n` +
      `--------------------------------------\n` +
      `<i>Auto-Release 任務執行完畢。</i>`;
  }

  return sendTelegramNotification(msg);
}


3. 連線單元測試

可在 Apps Script 中執行以下單元測試,驗證 Telegram Bot 能否正常發送修訂後的推播格式:

/**
 * Telegram Bot 單元連線測試
 */
function testTelegramBotNotification() {
  Logger.log("=== 開始 Telegram Bot 推播測試 ===");

  const testBooking = {
    bookingId: "BK_TEST_2026",
    roomName: "活動室 A1",
    userEmail: "worker@ngo.org",
    formattedStart: "2026-10-15 10:00",
    formattedEnd: "11:00",
    purpose: "跨組別青少年輔導工作坊"
  };

  const success = notifyNewBookingSuccess(testBooking);
  Logger.log("Telegram 推播測試結果: " + (success ? "成功 ✅" : "失敗 ❌"));
}


4. 小結

今天我們根據業務需求修正了 **Telegram Bot 即時通知與狀態異動推播機制 (TelegramBotService.gs)**推播訊息更加符合權限防護與簡潔原則。

明日繼續……


上一篇
【Day 22】簽到/簽退模組與 QR Code 驗證
下一篇
【Day 24】全系統錯誤處理、例外監控與 Log 日誌紀錄
系列文
零預算 NGO 數位轉型挑戰:30 天打造智慧訂房系統 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言